package main

import (
	"context"
	"flag"
	"fmt"
	"gitee.com/fh_jz/go-job/metrics"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"io"
	"log"
	"math/rand"
	"net"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func randInt(min int, max int) int {
	rand.Seed(time.Now().UTC().UnixNano())
	return min + rand.Intn(max-min)
}

/**
  处理
*/
func process(w http.ResponseWriter, r *http.Request) {
	timer := metrics.NewTimer()
	defer timer.ObserveTotal()
	user := r.URL.Query().Get("user")
	delay := randInt(10, 2000)
	time.Sleep(time.Millisecond * time.Duration(delay))
	if user != "" {
		io.WriteString(w, fmt.Sprintf("hello [%s]\n", user))
	} else {
		io.WriteString(w, "hello [stranger]\n")
	}

	//接收客户端 request，并将 request 中带的 header 写入 response header
	for k, v := range r.Header {
		log.Printf("debug: With head found key:%v; value: %v", k, v)
		w.Header().Add(k, fmt.Sprintf("%s", v))
	}

	//读取当前系统的环境变量中的 VERSION 配置，并写入 response header
	logVersion := os.Getenv("LOG_VERSION")
	w.Header().Add("LOG_VERSION", logVersion)

	//记录客户端IP
	remoteIp(r)

	io.WriteString(w, "get env log_version:"+logVersion)
}

/**
  记录客户端IP
*/
func remoteIp(req *http.Request) (ip string, err error) {
	ip, port, err := net.SplitHostPort(req.RemoteAddr)
	if err != nil {
		log.Printf("debug: Getting req.RemoteAddr %v", err)
		return "", err
	} else {
		log.Printf("debug: With req.RemoteAddr found IP:%v; Port: %v", ip, port)
	}
	userIP := net.ParseIP(ip)

	if userIP == nil {
		message := fmt.Sprintf("debug: Parsing IP from Request.RemoteAddr got nothing.")
		log.Printf(message)
		return "", fmt.Errorf(message)
	}

	log.Printf("debug: Found IP: %v", userIP)
	return userIP.String(), nil
}

/**
  健康检测
*/
func healthz(w http.ResponseWriter, r *http.Request) {
	//记录客户端IP
	remoteIp(r)

	io.WriteString(w, "200")
}

//func main() {
//	log.Printf("Starting http server...")
//	http.HandleFunc("/process", process)
//	http.HandleFunc("/healthz", healthz)
//	err := http.ListenAndServe(":8080", nil) // 设置监听的端口
//	if err != nil {
//		log.Fatal("ListenAndServe: ", err)
//	}
//}

func main() {
	flag.Set("v", "4")
	//glog.V(2).Info("Starting http server...")
	log.Printf("Starting http server...")
	metrics.Register()
	mux := http.NewServeMux()
	mux.HandleFunc("/process", process)
	mux.HandleFunc("/healthz", healthz)
	mux.Handle("/metrics", promhttp.Handler())

	srv := http.Server{
		Addr:    ":80",
		Handler: mux,
	}
	done := make(chan os.Signal, 1)
	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()
	log.Print("Server Started")
	<-done
	log.Print("Server Stopped")
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer func() {
		// extra handling here
		cancel()
	}()

	if err := srv.Shutdown(ctx); err != nil {
		log.Fatalf("Server Shutdown Failed:%+v", err)
	}
	log.Print("Server Exited Properly")
}
